package cn.sc.summer.token.encrypt;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.sc.summer.token.util.AESUtil;
import cn.sc.summer.constant.encrypt.EncryptKeyConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Base64;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 类名：加密算法工具类
 *
 * @author a-xin
 * @date 2023/9/5 11:27
 */
@Slf4j
@Component
public class EncryptUtil {

    /**
     * 随机生成数据长度
     */
    private static final Integer CODE_NUM = 10;

    /**
     * 自定义加密算法
     *
     * @param encryptStr 加密内容
     * @return 加密后字符串
     */
    public static String encrypt(String encryptStr) {
        if (StrUtil.isBlank(encryptStr)) {
            throw new RuntimeException("Requires encryption string cannot be empty!");
        }
        String randomKey = RandomUtil.randomString(16);
        String newText = AESUtil.encryptCBC(randomKey, EncryptKeyConstant.AES_SECURE_KEY) + "." + RandomUtil.randomString(8) + AESUtil.encryptCBC(ExchangeStrUtil.encryptStringToHex(encryptStr), randomKey);

        //获取随机数
        String randomNum = RandomUtil.randomString(CODE_NUM);
        char[] charArray = randomNum.toCharArray();
        //对随机数进行排序,生成list
        List<Integer> integerList = new ArrayList<>();
        for (int i = 0; i < charArray.length; i++) {
            integerList.add(Integer.parseInt(String.valueOf(charArray[i])));
        }
        //正序
        List<Integer> collect1 = integerList.stream().sorted().collect(Collectors.toList());

        //封装密文
        Base64.Encoder encoder = Base64.getEncoder();
        StringBuilder stringBuilder = new StringBuilder().append(encoder.encodeToString(newText.getBytes()));

        char[] randomCharArray = RandomUtil.randomString(CODE_NUM).toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            stringBuilder.insert(Integer.parseInt(String.valueOf(collect1.get(i))), randomCharArray[i]);
        }

        return stringBuilder.append(randomNum).toString();
    }

    /**
     * 自定义解密
     *
     * @param decryptStr 需要解密内容
     * @return 解密后字符串
     */
    public static String decrypt(String decryptStr) {
        if (StrUtil.isBlank(decryptStr)) {
            throw new RuntimeException("Requires decryption string cannot be empty!");
        }

        //获取随机数
        String randomNum = decryptStr.substring(decryptStr.length() - CODE_NUM);
        //获取随机密文
        String encryptText = decryptStr.substring(0, decryptStr.length() - CODE_NUM);

        char[] charArray = randomNum.toCharArray();
        //对随机数进行排序,生成list
        List<Integer> integerList = new ArrayList<>();
        for (int i = 0; i < charArray.length; i++) {
            integerList.add(Integer.parseInt(String.valueOf(charArray[i])));
        }
        //倒序
        List<Integer> collect = integerList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

        char[] charArray2 = encryptText.toCharArray();
        List<Character> charList = new String(charArray2).chars()
                .mapToObj(c -> (char) c)
                .collect(Collectors.toList());
        for (int i = 0; i < charArray.length; i++) {
            //替换顺序应该按照从大到小
            charList.remove(Integer.parseInt(String.valueOf(collect.get(i))));
        }
        StringBuilder stringBuilder = new StringBuilder();
        charList.stream().forEach(stringBuilder::append);

        String debase64 = new String(Base64.getDecoder().decode(stringBuilder.toString()));
        String[] split = debase64.split("\\.", 2);
        if (split.length > 1) {
            String substring = split[1].substring(8);
            String result = AESUtil.decryptCBC(substring, AESUtil.decryptCBC(split[0], EncryptKeyConstant.AES_SECURE_KEY));
            return ExchangeStrUtil.decryptStringFromHex(result);
        } else {
            return null;
        }
    }

}
